package com.eystar.ext.plugin.tablebind;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.eystar.ext.kit.UUIDKit;
import com.eystar.ext.kit.page.PageOrder;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.ActiveRecordException;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.activerecord.Table;
import com.jfinal.plugin.activerecord.TableMapping;

public class ModelExt<M extends ModelExt<M>> extends Model<M> {
	protected final Log logger = Log.getLog(getClass());
	private static final long serialVersionUID = -7530419393811458784L;
	private Class<? extends ModelExt<M>> clazz;
	private String deleteFlag = "delete_flag";
	private String primaryKey = "id";

	@SuppressWarnings("unchecked")
	public ModelExt() {
		Type genericSuperclass = getClass().getGenericSuperclass();
		clazz = (Class<? extends ModelExt<M>>) ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0];
	}
	
	@Override
	public boolean save(){
		Table tableInfo = getTable();
		
		// 如果有ID列，并且这一列的数据类型是String类型，说明不是自动增长的，需要自己设置值
    	if (tableInfo.hasColumnLabel(primaryKey) && tableInfo.getColumnType(primaryKey) == String.class && this.get(primaryKey) == null) {
            this.set(primaryKey, UUIDKit.nextShortUUID());
        }
		return super.save();
	}

	/**
	 * 查找所有对象
	 * 
	 * @return
	 */
	public List<M> find() {
		return findPseudo(false);
	}

	/**
	 * 查找delete_flag != 1的所有对象
	 * 
	 * @return
	 */
	public List<M> findSecurity() {
		return findPseudo(true);
	}
	
	private List<M> findPseudo(boolean deletePseudo){
    	String sql = "select * from " + tableName() + " where 1 = 1 ";
    	if (deletePseudo){
    		Table tableInfo = getTable();
        	if (!tableInfo.hasColumnLabel(deleteFlag)) {
                throw new ActiveRecordException("The deleteColumnLabel (" + deleteFlag + ") is not exist");
            }
            sql += " and "+deleteFlag + " <> 1 ";
		}
    	return find(sql);
    }

	/**
	 * 按某一列查找某一个对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public M findFirstByColumn(String column, Object value) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(column, value);
		List<M> result = findByColumns(map, true, false);
		return result.size() > 0 ? result.get(0) : null;
	}
	
	/**
	 * 按某一列查找某一个对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public M findFirstByColumns(Map<String, Object> columns) {
		List<M> result = findByColumns(columns, true, false);
		return result.size() > 0 ? result.get(0) : null;
	}
	
	/**
	 * 按某一列查找某一个delete_flag != 1的对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public M findFirstByColumnSecurity(String column, Object value) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(column, value);
		List<M> result = findByColumns(map, true, true);
		return result.size() > 0 ? result.get(0) : null;
	}
	
	/**
	 * 按某一列查找某一个delete_flag != 1的对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public M findFirstByColumnsSecurity(Map<String, Object> columns) {
		List<M> result = findByColumns(columns, true, true);
		return result.size() > 0 ? result.get(0) : null;
	}

	/**
	 * 按某一列查找某几个对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public List<M> findByColumn(String column, Object value) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(column, value);
		return findByColumns(map, false, false);
	}

	/**
	 * 按某一列查找某几个delete_flag != 1的对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public List<M> findByColumnSecurity(String column, Object value) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(column, value);
		return findByColumns(map, false, true);
	}
	
	/**
	 * 按某几列查找某几个对象
	 * 
	 * @param columns
	 * @param values
	 * @return
	 */
	public List<M> findByColumns(Map<String, Object> columns) {
		return findByColumns(columns, false, false);
	}

	/**
	 * 按某几列查找某几个delete_flag != 1的对象
	 * 
	 * @param columns
	 * @param values
	 * @return
	 */
	public List<M> findByColumnsSecurity(Map<String, Object> columns) {
		return findByColumns(columns, false, true);
	}
	
	private List<M> findByColumns(Map<String, Object> columns, boolean isFirst, boolean deletePseudo) {
		String sql = "select * from " + tableName() + " where 1 = 1";
		for (String column : columns.keySet()) {
			sql += " and " + column + " = ?";
		}
		if (deletePseudo) {
			sql += " and " + deleteFlag + " <> 1";
		}
		if (isFirst) {
			sql += " limit 1";
		}
		return find(sql, columns.values().toArray());
	}
	
	public SqlPara getSqlPara(String key,Model<M> model,PageOrder order){
		model.put("order", order.getOrder());
		model.put("orderType", order.getOrderType());
		SqlPara para = getSqlPara(key, model);
		para.addPara(order);
		return getSqlPara(key, model);
	}
	
	/**
	 * 按一列物理删除记录
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public int deleteByColumn(String column, Object value) {
		Map<String, Object> columns = new HashMap<String, Object>();
		columns.put(column, value);
		return deleteByColumns(columns);
	}
	
	/**
	 * 按ID假删除记录，将delete_flag 设置为 1，如果这个表没有ID列，删除会出现异常
	 * 
	 * @return
	 */
	public int deleteSecurity() {
		String id = getStr(primaryKey);
		return deleteByColumnSecurity(primaryKey, id);
	}
	
	/**
	 * 按ID集合物理删除记录
	 * 
	 * @param ids，格式为 1,2,3
	 * @return
	 */
	public int deleteByIds(String ids) {
		String sql = "delete from " + getTable().getName() + " where id in ('" + ids.replace(",", "','") + "')";
		return Db.update(sql);
	}
	
	/**
	 * 按ID集合假删除记录，将delete_flag 设置为 1
	 * 
	 * @param ids，格式为 1,2,3
	 * @return
	 */
	public int deleteByIdsSecurity(String ids) {
		String sql = "update " + getTable().getName() + " set delete_flag = 1 where id in ('" + ids.replace(",", "','") + "')";
		return Db.update(sql);
	}
	
	/**
	 * 按一列假删除记录，将delete_flag 设置为 1
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public int deleteByColumnSecurity(String column, Object value) {
		Map<String, Object> columns = new HashMap<String, Object>();
		columns.put(column, value);
		return deleteByColumnsSecurity(columns);
	}

	/**
	 * 按多列物理删除记录。
	 * 
	 * @param ids
	 * @return
	 */
	public int deleteByColumns(Map<String, Object> columns) {
		return deleteByColumns(columns, false);
	}

	/**
	 * 按多列假删除记录，将delete_flag 设置为 1
	 * 
	 * @param ids
	 * @return
	 */
	public int deleteByColumnsSecurity(Map<String, Object> columns) {
		return deleteByColumns(columns, true);
	}

	private int deleteByColumns(Map<String, Object> columns, boolean deletePseudo) {
		String sql = "";
		Table tableInfo = getTable();
		if (deletePseudo) {
			sql += "update " + tableInfo.getName() + " set " + deleteFlag + " = 1";
		} else {
			sql += "delete from " + tableInfo.getName();
		}
		sql += " where 1=1";
		for (String column : columns.keySet()) {
			sql += " and " + column + " = ?";
		}
		return Db.update(sql, columns.values().toArray());
	}

	private String tableName() {
		return getTable().getName();
	}
	
	private Table getTable(){
		return TableMapping.me().getTable(clazz);
	}
	
	/***
	 * 把 model 转化为 list 找到其中的单个属性
	 * 
	 * @param model
	 * @param attr
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> List<T> getAttr(List<M> model, String attr) {
		List<T> list = new ArrayList<T>();
		for (M t : model) {
			list.add((T) t.get(attr));
		}
		return list;

	}
}
